package com.example.ytyproject.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.ytyproject.config.exception.AppException;
import com.example.ytyproject.entity.Role;
import com.example.ytyproject.entity.User;
import com.example.ytyproject.entity.UserRole;
import com.example.ytyproject.entity.vo.R;
import com.example.ytyproject.mapper.UserMapper;
import com.example.ytyproject.mapper.UserRoleMapper;
import com.example.ytyproject.service.UserRoleService;
import com.example.ytyproject.service.UserService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yg
 * @since 2023-10-27
 */
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleService userRoleService;

    @Override
    public User findUsername(String name) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<User> lambda = queryWrapper.lambda();
        lambda.eq(User::getUsername, name);
        return this.getOne(lambda);
    }

    @Override
    public R listByPage(User user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        LambdaQueryWrapper<User> lambda = queryWrapper.lambda();
        lambda.orderByDesc(User::getCreateDate);
        if (StringUtils.isNotEmpty(user.getMobile())) {
            lambda.like(User::getMobile, user.getMobile());
        }
        if (StringUtils.isNotEmpty(user.getAddress())) {
            lambda.like(User::getAddress, user.getAddress());
        }
        Page<User> page = this.page(new Page<>(user.getPageNo(), user.getPageSize()), queryWrapper);
        return R.ok(page.getRecords(), page.getTotal());
    }

    @Override
    public void addUser(User paramUser) {
        User user = findByUserName(paramUser.getMobile());
        if (user != null) {
            throw new AppException("手机号已存在！");
        }
        if(StringUtils.isNotEmpty(paramUser.getPassword())) {
            paramUser.setPassword(DigestUtils.md5Hex(paramUser.getPassword()));
        }
        paramUser.setCreateDate(LocalDateTime.now()).setUsername(paramUser.getMobile());
        this.save(paramUser);
    }

    @Override
    public User findByUserName(String username) {
        User user = this.getOne(new QueryWrapper<User>().lambda().eq(User::getUsername, username));
        return user;
    }

    @Override
    public void updateUser(User paramUser) {
        User user = findByUserName(paramUser.getMobile());
        if (user == null) {
            paramUser.setUpdateDate(LocalDateTime.now());
            this.updateById(paramUser);
            return;
        }
        if (!user.getId().equals(paramUser.getId())) {
            throw new AppException("手机号已存在！");
        }
        paramUser.setUpdateDate(LocalDateTime.now());
        this.updateById(paramUser);
    }

    @Override
    public R login(User user) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        try {
            // 登录验证
            subject.login(token);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("access_token", "bqddxxwqmfncffacvbpkuxvwvqrhln");
            return R.ok(jsonObject);
        } catch (UnknownAccountException e) {
            throw new AppException("账户不存在！");
        } catch (DisabledAccountException e) {
            throw new AppException("账户不可用！");
        } catch (IncorrectCredentialsException e) {
            throw new AppException("账户无权限！");
        } catch (Throwable e) {
            e.printStackTrace();
            throw new AppException("用户名或密码错误！");
        }
    }

    @Override
    public void roleAllocation(List<Role> roles) {
        String userId = roles.get(0).getUserId();
        if (StringUtils.isEmpty(userId)) {
            throw new AppException("请选择用户！");
        }
        // 删除原有角色
        userRoleService.remove(new QueryWrapper<UserRole>().lambda().eq(UserRole::getUserId, userId));
        // ruku
        List<UserRole> data = new ArrayList<>();
        for (Role role : roles) {
            UserRole userRole = new UserRole();
            userRole.setRoleId(role.getId()).setUserId(role.getUserId());
            data.add(userRole);
        }
        if (data.size() > 0) {
            ArrayList<UserRole> collect = data.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getUserId() + ";" + o.getRoleId()))), ArrayList::new));
            userRoleService.saveBatch(collect);
        }
    }
}














